home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Examples / Simple / Simple.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-06  |  11.7 KB  |  399 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // Simple.c
  3. ///--------------------------------------------------------------------------------------
  4.  
  5. #include <SWIncludes.h>            // Automatically include all SpriteWorld headers
  6. #include <SWGameUtils.h>
  7. #include <SWFPSReport.h>
  8.  
  9. #include "SWApplication.h"
  10. #include "Simple.h"
  11.  
  12.  
  13. #define kFullScreenWindow        false        // Set to true if you want a window larger than 640x480 
  14. #define kInterlacedMode            false        // You can use interlacing even with non-scrolling animations
  15. #define kSyncToVBL                false        // Syncs the animation to the VBL
  16. #define kWorldRectInset            0            // Makes the SpriteWorld smaller than the window.
  17. #define kMaxFPS                    30            // Keep the animation from going too fast
  18.  
  19. #define kNumSprites                10
  20. #define kMaxSpriteMoveDelta        8
  21.  
  22. #define kUseShadows                true        // Adds shadows below each Sprite!
  23. #define kShadowOffset            13            // Number of pixels to offset each shadow
  24.  
  25.  
  26. SpriteWorldPtr        gSpriteWorldP;
  27. SpriteLayerPtr        gSpriteLayerP, gShadowSpriteLayerP;
  28. SpritePtr            gMasterBallSpriteP;
  29. WindowPtr            gWindowP;
  30.  
  31.  
  32. ///--------------------------------------------------------------------------------------
  33. // main
  34. ///--------------------------------------------------------------------------------------
  35.  
  36. void main(void)
  37. {
  38.     Initialize(kNumberOfMoreMastersCalls);
  39.     Randomize();
  40.  
  41.     if (SWHasSystem7())
  42.     {
  43.         HideControlStrip();
  44.         SWSetCleanUpFunction(MyCleanUpFunction);
  45.         
  46.         CreateWindow();
  47.         SetUpSpriteWorld();
  48.         CreateBallSprite();
  49.         
  50.         AddSprites();
  51.         RunAnimation();
  52.         CleanUp();
  53.         
  54.         RestoreControlStrip();
  55.     }
  56.     else
  57.     {
  58.         CantRunOnThisMachine();
  59.     }
  60. }
  61.  
  62.  
  63. ///--------------------------------------------------------------------------------------
  64. //    CreateWindow
  65. ///--------------------------------------------------------------------------------------
  66.  
  67. void    CreateWindow(void)
  68. {
  69.     Rect        windRect;
  70.     RgnHandle    mBarUpdateRgn;
  71.     
  72.     gWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
  73.  
  74.     if (gWindowP != NULL)
  75.     {
  76.         if (kFullScreenWindow == true)
  77.         {
  78.             SizeWindow(gWindowP, qd.screenBits.bounds.right, 
  79.                             qd.screenBits.bounds.bottom, false);
  80.             MoveWindow(gWindowP, 0, 0, false);
  81.         }
  82.         else
  83.         {
  84.             MoveWindow(gWindowP, 0, 0, false);
  85.             windRect = gWindowP->portRect;
  86.             
  87.                 // Make sure the window fits on the screen
  88.             if (windRect.bottom > qd.screenBits.bounds.bottom ||
  89.                  windRect.right > qd.screenBits.bounds.right)
  90.             {
  91.                     // Make it smaller so it fits on the screen
  92.                 SizeWindow(gWindowP, qd.screenBits.bounds.right, 
  93.                                 qd.screenBits.bounds.bottom, false);
  94.                 MoveWindow(gWindowP, 0, 0, false);
  95.             }
  96.             else
  97.             {
  98.                     // Center window in screen
  99.                 CenterRect(&windRect, &qd.screenBits.bounds);
  100.                 MoveWindow(gWindowP, windRect.left, windRect.top, false);
  101.             }
  102.         }
  103.         
  104.         ShowWindow(gWindowP);
  105.         SetPort(gWindowP);
  106.         mBarUpdateRgn = SWHideMenuBar(gWindowP); // Must be done *after* showing window!
  107.         EraseRgn(mBarUpdateRgn);
  108.     }
  109.     else
  110.         CantFindResource();
  111. }
  112.  
  113.  
  114. ///--------------------------------------------------------------------------------------
  115. //    SetUpSpriteWorld
  116. ///--------------------------------------------------------------------------------------
  117.  
  118. void    SetUpSpriteWorld(void)
  119. {
  120.     OSErr            err;
  121.     Rect            worldRect;
  122.     PixPatHandle    pixPatH;
  123.  
  124.     SetCursor(*GetCursor(watchCursor));
  125.  
  126.         // Initialize the SpriteWorld package
  127.     err = SWEnterSpriteWorld();
  128.     FatalError(err);
  129.     
  130.     worldRect = gWindowP->portRect;
  131.     InsetRect(&worldRect, kWorldRectInset, kWorldRectInset);
  132.     
  133.         // Create the SpriteWorld
  134.     err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP, 
  135.         &worldRect, NULL, 0);
  136.     FatalError(err);
  137.  
  138.         // Create the Sprite Layers
  139.     err = SWCreateSpriteLayer(&gSpriteLayerP);
  140.     FatalError(err);
  141.     err = SWCreateSpriteLayer(&gShadowSpriteLayerP);
  142.     FatalError(err);
  143.     
  144.         // Put the pieces together and lock the SpriteWorld. 
  145.         // Note: since we are locking the SpriteWorld before adding the sprites,
  146.         // we must make sure to lock each sprite individually when creating them.
  147.     SWAddSpriteLayer(gSpriteWorldP, gShadowSpriteLayerP);
  148.     SWAddSpriteLayer(gSpriteWorldP, gSpriteLayerP);
  149.     SWLockSpriteWorld(gSpriteWorldP);
  150.     
  151.     
  152.         // Use BlitPixie for the screen and offscreen DrawProcs.
  153.     if (gSpriteWorldP->pixelDepth >= 8)        // 8-bit, 16-bit, and 32-bit blitter
  154.     {
  155.         SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixieRectDrawProc);
  156.         SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieRectDrawProc);
  157.     }
  158.     else if ( SW_68K )    // Use AllBit blitter when in depths lower than 8-bits on 68k.
  159.     {
  160.         SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  161.         SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  162.     }
  163.     
  164.     if (kInterlacedMode)
  165.     {
  166.         SWSetFrameInterlacingMode(gSpriteWorldP->workFrameP, true, kSkipOddLines);
  167.         SWSetFrameInterlacingMode(gSpriteWorldP->windowFrameP, true, kSkipOddLines);
  168.     }
  169.     
  170.     SWSetPortToWorkArea(gSpriteWorldP);
  171.     PaintRect(&gSpriteWorldP->backRect);
  172.  
  173.         // Draw the background
  174.     SWSetPortToBackground(gSpriteWorldP);
  175.     
  176.     if (gSpriteWorldP->pixelDepth == 1)
  177.         pixPatH = GetPixPat(129);        // B&W dithered background
  178.     else
  179.         pixPatH = GetPixPat(128);        // Color
  180.     
  181.     if (pixPatH != NULL)
  182.     {
  183.         FillCRect(&gSpriteWorldP->backRect, pixPatH);
  184.         DisposePixPat(pixPatH);
  185.     }
  186.     
  187.         // Set up other miscellaneous options
  188.     SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
  189.     SWSyncSpriteWorldToVBL(gSpriteWorldP, kSyncToVBL);
  190.     SWSetCleanUpSpriteWorld(gSpriteWorldP);
  191. }
  192.  
  193.  
  194. ///--------------------------------------------------------------------------------------
  195. //    CreateBallSprite - load the master ball sprite and prepare it for cloning later
  196. ///--------------------------------------------------------------------------------------
  197.  
  198. void    CreateBallSprite(void)
  199. {
  200.     OSErr    err;
  201.     
  202.     err = SWCreateSpriteFromCicnResource(gSpriteWorldP, &gMasterBallSpriteP, NULL, 
  203.             128, 1, kFatMask);
  204.     FatalError(err);
  205.  
  206.         // Set up the sprite (remember that it must be locked!)
  207.     SWLockSprite(gMasterBallSpriteP);
  208.     SWSetSpriteMoveBounds(gMasterBallSpriteP, &gSpriteWorldP->backRect);
  209.     SWSetSpriteMoveProc(gMasterBallSpriteP, BallSpriteMoveProc);
  210.     
  211.         // Set the sprite's drawProc
  212.     if (gSpriteWorldP->pixelDepth >= 8)        // 8-bit, 16-bit, and 32-bit blitter
  213.     {
  214.         SWSetSpriteDrawProc(gMasterBallSpriteP, BlitPixieMaskDrawProc);
  215.     }
  216.     else if ( SW_68K )                        // 68k blitter for any depth
  217.     {
  218.         SWSetSpriteDrawProc(gMasterBallSpriteP, BlitPixieAllBitMaskDrawProc);
  219.     }
  220. }
  221.  
  222.  
  223. ///--------------------------------------------------------------------------------------
  224. //    AddSprites - clone the master sprite, and add the clones to the SpriteWorld
  225. ///--------------------------------------------------------------------------------------
  226.  
  227. void    AddSprites(void)
  228. {
  229.     SpritePtr    newSpriteP, shadowSpriteP;
  230.     short        spriteNum;
  231.     OSErr        err;
  232.     
  233.     for (spriteNum = 0; spriteNum < kNumSprites; spriteNum++)
  234.     {
  235.             // Clone the master sprite. The clone doesn't need to be locked,
  236.             // since the master sprite was already locked.
  237.         err = SWCloneSprite(gMasterBallSpriteP, &newSpriteP, NULL);
  238.         FatalError(err);
  239.         
  240.         SWAddSprite(gSpriteLayerP, newSpriteP);
  241.         
  242.         SWSetSpriteLocation(newSpriteP,
  243.                 GetRandom(0, gSpriteWorldP->backRect.right-44), 
  244.                 GetRandom(0, gSpriteWorldP->backRect.bottom-44) );
  245.         
  246.         do
  247.         {
  248.             SWSetSpriteMoveDelta(newSpriteP,
  249.                     GetRandom(-kMaxSpriteMoveDelta, kMaxSpriteMoveDelta), 
  250.                     GetRandom(-kMaxSpriteMoveDelta, kMaxSpriteMoveDelta));
  251.         } while (newSpriteP->horizMoveDelta == 0 || newSpriteP->vertMoveDelta == 0);
  252.     
  253.         if (kUseShadows == true)
  254.         {
  255.                 // Create the shadow Sprite
  256.             err = SWCloneSprite(gMasterBallSpriteP, &shadowSpriteP, NULL);
  257.             FatalError(err);
  258.             
  259.             SWAddSprite(gShadowSpriteLayerP, shadowSpriteP);
  260.             SWSetSpriteLocation(shadowSpriteP,
  261.                 newSpriteP->destFrameRect.left + kShadowOffset, 
  262.                 newSpriteP->destFrameRect.top + kShadowOffset);
  263.             SWSetSpriteDrawProc(shadowSpriteP, ShadowSpriteDrawProc);
  264.             
  265.                 // Store a pointer to the shadow Sprite in the parent Sprite's userData field
  266.             newSpriteP->userData = (long)shadowSpriteP;
  267.         }
  268.         else
  269.         {
  270.             newSpriteP->userData = 0L;
  271.         }
  272.     }
  273. }
  274.  
  275.  
  276. ///--------------------------------------------------------------------------------------
  277. //    RunAnimation
  278. ///--------------------------------------------------------------------------------------
  279.  
  280. void    RunAnimation(void)
  281. {
  282.     unsigned long    frames;
  283.     
  284.     SetCursor(&qd.arrow);
  285.     HideCursor();
  286.     
  287.         // Make sure CopyBits, if used, doesn't try to colorize things
  288.     SWSetPortToWindow(gSpriteWorldP);
  289.     ForeColor(blackColor);
  290.     BackColor(whiteColor);
  291.     
  292.     SWUpdateSpriteWorld(gSpriteWorldP, true);
  293.     
  294.     FatalError( SWStickyError() ); // Make sure no errors got past us during setup
  295.     
  296.     frames = 0;
  297.     StartTimer();    // For FPS report later
  298.     
  299.     while (!Button())
  300.     {
  301.         SWProcessSpriteWorld(gSpriteWorldP);
  302.         FatalError( SWStickyError() );    // Make sure no errors occurred during a MoveProc, etc.
  303.         SWAnimateSpriteWorld(gSpriteWorldP);
  304.         
  305.         if (gSpriteWorldP->frameHasOccurred)
  306.             frames++;        
  307.     }
  308.     
  309.     SWShowMenuBar((WindowPtr)gWindowP);
  310.     ShowResults(frames);    // Show FPS report
  311. }
  312.  
  313.  
  314. ///--------------------------------------------------------------------------------------
  315. //     CleanUp - This function is not really necessary, since the system will dispose
  316. //    everything automatically when the program quits. However, if you sync the animation
  317. //    to the VBL, you must either call SWDisposeSpriteWorld, or SWSyncSpriteWorldToVBL
  318. //    with a value of false before your program quits, in order to remove the VBL task.
  319. ///--------------------------------------------------------------------------------------
  320.  
  321. void    CleanUp(void)
  322. {
  323.         // Dispose the master sprite, since it isn't included in the SpriteWorld
  324.     SWDisposeSprite(&gMasterBallSpriteP);
  325.     
  326.         // Dispose the SpriteWorld, including all sprites and layers currently in it
  327.     SWDisposeSpriteWorld(&gSpriteWorldP);
  328.     SWExitSpriteWorld();
  329.     
  330.     FlushEvents(everyEvent, 0);
  331.     InitCursor();
  332. }
  333.  
  334.  
  335. ///--------------------------------------------------------------------------------------
  336. //  MyCleanUpFunction - called if an error occurs, to clean up before quitting
  337. ///--------------------------------------------------------------------------------------
  338.  
  339. void    MyCleanUpFunction( void )
  340. {
  341.     SWShowMenuBar(gWindowP);
  342.     RestoreControlStrip();
  343. }
  344.  
  345.  
  346. ///--------------------------------------------------------------------------------------
  347. //  BallSpriteMoveProc
  348. ///--------------------------------------------------------------------------------------
  349.  
  350. SW_FUNC void BallSpriteMoveProc(SpritePtr ballSpriteP)
  351. {    
  352.     SWOffsetSprite(ballSpriteP, ballSpriteP->horizMoveDelta, ballSpriteP->vertMoveDelta);
  353.     
  354.     (void)SWBounceSprite(ballSpriteP);
  355.     //(void)SWWrapSprite(ballSpriteP);
  356.     
  357.         // Move this Sprite's shadow, if there is one.
  358.     if (ballSpriteP->userData != 0L)
  359.     {
  360.         SpritePtr    shadowSpriteP = (SpritePtr)ballSpriteP->userData;
  361.         
  362.         SWMoveSprite(shadowSpriteP, 
  363.             ballSpriteP->destFrameRect.left + kShadowOffset - 5, 
  364.             ballSpriteP->destFrameRect.top + kShadowOffset);
  365.     }
  366. }
  367.  
  368.  
  369. ///--------------------------------------------------------------------------------------
  370. //  ShadowSpriteDrawProc - uses the Sprite's region, but not image, to "tint" the 
  371. //  area underneath the Sprite the color you specify. Note: Brian's Utils would do this faster!
  372. ///--------------------------------------------------------------------------------------
  373.  
  374. #define kShadowDarkness            0x5000        // Controls the shadow's darkness
  375.  
  376. SW_FUNC void ShadowSpriteDrawProc(FramePtr srcFrameP, FramePtr dstFrameP, 
  377. Rect* srcRect, Rect* dstRect)
  378. {
  379.     #pragma        unused(dstFrameP, srcRect)
  380.     RGBColor    col;
  381.     PenState    pnState;
  382.     RgnHandle    theRgn;
  383.     
  384.     theRgn = NewRgn();
  385.     CopyRgn(srcFrameP->maskRgn, theRgn);
  386.     OffsetRgn(theRgn, dstRect->left, dstRect->top);
  387.     col.red = kShadowDarkness;
  388.     col.green = kShadowDarkness;
  389.     col.blue = kShadowDarkness;
  390.     RGBForeColor(&col);
  391.     GetPenState(&pnState);
  392.     PenMode(subPin);
  393.     PaintRgn(theRgn);
  394.     PenMode(0);
  395.     SetPenState(&pnState);
  396.     DisposeRgn(theRgn);
  397.     ForeColor(blackColor);
  398. }
  399.